package pl.matt.main;


import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import pl.matt.media.extractor.FramesExtractor;
import pl.matt.media.extractor.impl.EyesExtractor;
import pl.matt.media.extractor.impl.FacesExtractor;
import pl.matt.media.extractor.impl.MplayerFramesExtractor;
import pl.matt.media.extractor.impl.NoseExtractor;
import pl.matt.media.manager.MediaManagersFactory;
import pl.matt.media.model.ImageType;
import pl.matt.media.parser.FaceParser;
import pl.matt.media.parser.impl.FaceParserImpl;
import pl.matt.media.procesor.FrameProcessor;
import pl.matt.media.procesor.impl.RectangleCutFrameProcessor;
import pl.matt.media.procesor.impl.VerticalDivideFrameProcessor;
import pl.matt.model.Rectangle;

@Deprecated
public class Main {

	//@SuppressWarnings("unused")
	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(Main.class);
	
	/**
	 * http://www.quasimondo.com/archives/000687.php
	 * rozbiór zdjęcia na twarz, oczy, nos i usta
	 * 
	 * @param args
	 * @throws IOException 
	 */
	public static void oldMain(String[] args) throws IOException {
		FramesExtractor extractor = new MplayerFramesExtractor();
		extractor.extractFrames("resources/movies/2009-08-10-010344.ogv", "/tmp/frames/");
		FaceParser parser = new FaceParserImpl();
		String framesDir = "/tmp/frames";
		File dir = new File(framesDir);
		File[] frames = dir.listFiles();
		for (int i = 0; i < frames.length; i++) {
			File file = frames[i];
			File frameDir = new File(framesDir + "/" + i);
			frameDir.mkdir();
			try {
				parser.parse(file.getAbsolutePath(), frameDir.getAbsolutePath());
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}	

	}
	
	public static void main(String[] args) throws IOException {
		boolean clean = true;
		boolean extractFrames = true;
		boolean extractFaces = true;
		boolean divideFaces = true;
		boolean extractEyeRegions = true;
		boolean extractEyes = true;
		boolean extractNoseRegions = true;
		boolean extractNoses = true;
		boolean extractMouthRegions = true;
		//boolean extractMouths = true;
		
		String framesDir = "/tmp/frames2";
		//String framesDir = "resources/images/testFaces";
		File allFramesDir = new File(framesDir);
		if (clean) {
			if (allFramesDir.exists() && !allFramesDir.delete()) {
				LOG.error("nie mogę wyczyścić katalogu: " + framesDir);
				Process p = Runtime.getRuntime().exec("rm -rf " + framesDir);
				try {
					p.waitFor();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					LOG.error("clean failed");
				}
				LOG.debug(p.exitValue() + " <-- p.exitValue()");
			}
		}
		if (extractFrames) {
			FramesExtractor framesExtractor = new MplayerFramesExtractor();
			framesExtractor.extractFrames("resources/movies/2009-08-10-010344.ogv", framesDir);
		}
		File[] allFramesDirContent = allFramesDir.listFiles();
		final String faceFileNameWithoutExt = "face";
		if (extractFaces) {
			FacesExtractor extractor = new FacesExtractor(framesDir, faceFileNameWithoutExt);
			extractor.extract();
		}
		
		if (divideFaces) {
			FrameProcessor verticalDivideFrameProcessor = new VerticalDivideFrameProcessor();
			allFramesDirContent = allFramesDir.listFiles();
			for (File file : allFramesDirContent) {
				if (file.isDirectory()) {
					File[] frames = file.listFiles();
					for (File frame : frames) {
						verticalDivideFrameProcessor.processFrame(frame.getAbsolutePath());
					}
				}
			}
		}
		String leftEyeRegionSiffix = "left_eye_region";
		String rightEyeRegionSiffix = "right_eye_region";
		if (extractEyeRegions) {
			allFramesDirContent = allFramesDir.listFiles();
			FrameProcessor leftEyeRegionProcessor = new RectangleCutFrameProcessor(faceFileNameWithoutExt + "_" + leftEyeRegionSiffix + ".jpg", 15, 10, 85, 50);
			FrameProcessor rightEyeRegionProcessor = new RectangleCutFrameProcessor(faceFileNameWithoutExt + "_" + rightEyeRegionSiffix + ".jpg", 0, 10, 85, 50);
			for (File file : allFramesDirContent) {
				if (file.isDirectory()) {
					File[] leftFaces = file.listFiles(new FileFilter() {
						
						@Override
						public boolean accept(File pathname) {
							return pathname.getName().endsWith("_l.jpg");
						}
					});
					for (File frame : leftFaces) {
						leftEyeRegionProcessor.processFrame(frame.getAbsolutePath());
					}
					File[] rightFaces = file.listFiles(new FileFilter() {
						
						@Override
						public boolean accept(File pathname) {
							return pathname.getName().endsWith("_r.jpg");
						}
					});
					for (File frame : rightFaces) {
						rightEyeRegionProcessor.processFrame(frame.getAbsolutePath());
					}
				}
			}
		}
		String leftEyeSiffix = "left_eye";
		String rightEyeSiffix = "right_eye";
		List<Rectangle> leftEyes = null;
		List<Rectangle> rightEyes = null;
		if (extractEyes) {
			EyesExtractor leftEyeExtractor = new EyesExtractor(allFramesDir, leftEyeRegionSiffix, leftEyeSiffix);
			leftEyes = leftEyeExtractor.extract();
			EyesExtractor rightEyeExtractor = new EyesExtractor(allFramesDir, rightEyeRegionSiffix, rightEyeSiffix);
			rightEyes = rightEyeExtractor.extract();
		}
		String noseRegionFileNameWithoutExt = "nose_region";
		
		List<Rectangle> noseRegions = null;
		List<Rectangle> noses = null;
		if (extractNoseRegions && extractEyes) {
			allFramesDirContent = allFramesDir.listFiles();
			int index = 0;
			noseRegions = new ArrayList<Rectangle>(allFramesDirContent.length);
			for (File file : allFramesDirContent) {
				if (file.isDirectory()) {
					File[] faces = file.listFiles(new FilenameFilter() {
						
						@Override
						public boolean accept(File dir, String name) {
							return name.startsWith(faceFileNameWithoutExt + ".");
						}
					});
					Rectangle leftEyeRegion = leftEyes.get(index);
					Rectangle rightEyeRegion = rightEyes.get(index);
					File face = faces[0];
					Rectangle faceRectangle = MediaManagersFactory.getImageManager().getImageRectangle(face);
					int faceYOffset = (int) (faceRectangle.getHeight() * 0.1);
					int faceXOffset = (int) (faceRectangle.getWidth() * 0.075);
					
					int x = faceXOffset + leftEyeRegion.getMiddleX();
					int y = faceYOffset + leftEyeRegion.getMiddleY()/2 + rightEyeRegion.getMiddleY()/2;
					int width = faceRectangle.getWidth()/2 - faceXOffset - leftEyeRegion.getMiddleX() + rightEyeRegion.getMiddleX();
					Rectangle noseRectangle = new Rectangle(x, y, width, (int) (width * 1.25));
					noseRegions.add(noseRectangle);
					String destinationImagePath = face.getAbsolutePath().replace(faceFileNameWithoutExt, noseRegionFileNameWithoutExt);
					MediaManagersFactory.getImageManager().cropImage(face.getAbsolutePath(), destinationImagePath, noseRectangle, ImageType.JPEG);
					index++;
				}
			}
		}
		String noseFileNameWithoutExt = "nose";
		if (extractNoses) {
			NoseExtractor noseExtractor = new NoseExtractor(allFramesDir, noseRegionFileNameWithoutExt, noseFileNameWithoutExt);
			noses = noseExtractor.extract();
		}
		String mouthRegionFileNameWithoutExt = "mouthRegion";
		if (extractMouthRegions && extractNoseRegions && extractEyes) {
			allFramesDirContent = allFramesDir.listFiles();
			LOG.debug(allFramesDirContent.length + " <-- allFramesDirContent.length");
			int index = 0;
			for (File file : allFramesDirContent) {
				if (file.isDirectory()) {
					File[] faces = file.listFiles(new FilenameFilter() {
						
						@Override
						public boolean accept(File dir, String name) {
							return name.startsWith(faceFileNameWithoutExt + ".");
						}
					});
					Rectangle noseRegion = noseRegions.get(index);
					Rectangle nose = noses.get(index);
					File face = faces[0];
					Rectangle faceRectangle = MediaManagersFactory.getImageManager().getImageRectangle(face);
					int y = noseRegion.getY() + nose.getY() + nose.getMiddleX();
					int x = noseRegion.getX();
					int width = noseRegion.getWidth();
					int height = faceRectangle.getHeight() - y;
					LOG.debug(allFramesDirContent[index] + ": " + height + " <-- height | " + y + " <-- y | " + faceRectangle.getHeight() + " <-- faceRectangle.getHeight()");
					Rectangle noseRectangle = new Rectangle(x, y, width, height);
					String destinationImagePath = face.getAbsolutePath().replace(faceFileNameWithoutExt, mouthRegionFileNameWithoutExt);
					MediaManagersFactory.getImageManager().cropImage(face.getAbsolutePath(), destinationImagePath, noseRectangle, ImageType.JPEG);
					index++;
				}
			}
		}

	}
	

}
